/**
@author		Jong Min, Lee
@date		  01/21/2014
@brief		viewer class

copyright(c) Tae Young Soft. All right reserved. 2014
*/
#include "stdafx.h"
#include "Taurus_Viewer/Viewer.h"

#include "Taurus_Common/IAppGlobalInstanceSet.h"
#include "Taurus_Common/MonitorAdmin.h"
#include "Taurus_Common/Monitor.h"
#include "Taurus_Common/IWorklistModule.h"
#include "Taurus_ToolData/ToolDataAdmin.h"
#include "Taurus_Util/Errors.h"
#include "Taurus_Viewer/VGlobalInstanceSet.h"
#include "Taurus_Viewer/Logger.h"
#include "Taurus_Viewer/ViewerProperty.h"
#include "Taurus_Viewer/ToolbarProperty.h"
#include "Taurus_Viewer/ViewerController.h"

CViewer::CViewer()
{}

CViewer::~CViewer()
{}

DWORD CViewer::init(IAppGlobalInstanceSet* pInstanceSet)
{
  CVGlobalInstanceSet* pVGSet = CVGlobalInstanceSet::getInstance();
  pVGSet->setAppGlobalInstanceSet(pInstanceSet);

  return ERROR_SUCCESS;
}

DWORD CViewer::destroy()
{
  ///TODO(Jong Min, Lee)
  return ERROR_SUCCESS;
}

DWORD CViewer::setProperty(MSXML2::IXMLDOMDocument2Ptr pPropertyDoc)
{
  //initialize viewer property
  DWORD dwError = initViewerProperty(pPropertyDoc);
  if(dwError != ERROR_SUCCESS)
    return dwError;

  CVGlobalInstanceSet* pVGSet = CVGlobalInstanceSet::getInstance();
  IAppGlobalInstanceSet* pAppGSet = pVGSet->getAppGlobalInstanceSet();

  //load tool data 
  CMonitorAdmin* pMAdmin = pAppGSet->getMonitorAdmin();
  dwError = pMAdmin->doConfigure(CViewerProperty::getInstance());
  if(dwError != ERROR_SUCCESS)
  {
    TAURUS_VIEWER_ERROR("CViewer::setProperty(): "
      "fails to configure monitor setting");
    return dwError;
  }

  //check if high resolution monitor is exist
  const CMonitor* pHighResMonitor = pMAdmin->findMonitorIf(
    [](const CMonitor* pMonitor)
  {
    return (pMonitor->getResolutionType() != MonitorResolution_Normal);
  });
  BOOL bExist2K = pHighResMonitor != NULL;
  CToolDataAdmin* pTA = pVGSet->getToolDataAdmin();
  dwError = pTA->loadData(bExist2K);
  if(dwError != ERROR_SUCCESS)
  {
    TAURUS_VIEWER_ERROR("CViewer::setProperty(): "
      "fails to load tool data");
    return dwError;
  }
  
  //configure toolbar property
  CToolbarProperty* pTBProp = CToolbarProperty::getInstance();
  dwError = pTBProp->importProperty();
  if(dwError != ERROR_SUCCESS)
  {
    TAURUS_VIEWER_ERROR("CViewer::setProperty(): "
      "fails to import toolbar property");
    return dwError;
  }

  const CMonitor* pWorklistMonitor = pMAdmin->getInitWorklistMonitor();
  if(pWorklistMonitor != NULL)
  {
    IWorklistModule* pWorklist = pAppGSet->getWorklist();
    pWorklist->showWorklist(pWorklistMonitor, TRUE);
  }

  CViewerController* pVC = CViewerController::getInstance();
  pVC->doConfigure();

  return ERROR_SUCCESS;
}

DWORD CViewer::ShowViewer(const CMonitor* pMonitor)
{
  CViewerController* pVC = CViewerController::getInstance();
  return pVC->ShowViewer(pMonitor);
}

DWORD CViewer::initViewerProperty(MSXML2::IXMLDOMDocument2Ptr pPropertyDoc)
{
  CViewerProperty* pVProperty = CViewerProperty::getInstance();

  DWORD dwError = ERROR_SUCCESS;
  if(pPropertyDoc == NULL)
  {
    TAURUS_VIEWER_WARN("CViewer::initViewerProperty(): "
      << "viewer property xml document is null. "
      << "we try to create empty viewer property xml document.");

    MSXML2::IXMLDOMDocument2Ptr pVPropertDoc = NULL;
    pVPropertDoc = XmlFunc::CreateXmlDoc(VIEWER_PROPERTY_NAME,
                                         NULL,
                                         NULL);
    if(pVPropertDoc == NULL)
    {
      TAURUS_VIEWER_ERROR("CViewer::initViewerProperty(): can't create empty viewer property xml document.");
      return ERROR_XML_PARSER;
    }

    dwError = pVProperty->setProperty(pVPropertDoc);
  }//if(pPropertyDoc == NULL)
  else
  {
    dwError = pVProperty->setProperty(pPropertyDoc);
    if(dwError != ERROR_SUCCESS && dwError != ERROR_VIEWER_PROPERTY_NOT_FOUND)
      return dwError;

    //if viewer property xml node is not found,
    //we try to create empty viewer property xml documnet
    if(dwError == ERROR_VIEWER_PROPERTY_NOT_FOUND)
    {
      TAURUS_VIEWER_WARN("CViewer::initViewerProperty(): "
        << "viewer property xml node is not found. we try to create empty viewer property xml node");

      //convert viewer preoperty document that is passed to string
      CString strXml;
      try
      {
        if(!XmlFunc::GetOuterXml(pPropertyDoc, strXml))
        {
          TAURUS_VIEWER_ERROR("CViewer::initViewerProperty(): "
            << "viewer property xml document can't be converted to string, "
            << "because an error occurs in xml parser module.");
          return ERROR_XML_PARSER;
        }
      }
      catch(CMemoryException* e)
      {
        TAURUS_VIEWER_ERROR("CViewer::initViewerProperty(): "
          << "viewer property xml document can't be converted to string, "
          << "because it is tool long.");
        
        e->Delete();
        return ERROR_NOT_ENOUGH_MEMORY;
      }

      //load viewer property xml string
      MSXML2::IXMLDocument2Ptr pCloneDoc = XmlFunc::LoadXmlDocString(strXml);
      if(pCloneDoc == NULL)
      {
        TAURUS_VIEWER_ERROR("CViewer::initViewerProperty(): "
          << "viewer property xml document string can't be loaded, "
          << "because an error occurs in xml parser module");
        return ERROR_XML_PARSER;
      }

      //create viewer property xml node
      MSXML2::IXMLDOMNodePtr pRootNode = XmlFunc::GetRoot(pCloneDoc);
      MSXML2::IXMLDOMNodePtr pNewPropertyNode = XmlFunc::CreateNewChild(
        pRootNode, VIEWER_PROPERTY_NAME);
      if(pNewPropertyNode == NULL)
      {
        TAURUS_VIEWER_ERROR("CViewer::initViewerProperty() : "
          << "viewer property xml node can't be created, "
          << "because an error occurs xml parser module.");
        return ERROR_XML_PARSER;
      }

      dwError = pVProperty->setProperty(pCloneDoc);
    }
  }//else

  return dwError;
}
